{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import asyncio\n",
    "import os\n",
    "import asyncio\n",
    "\n",
    "from typing import Annotated\n",
    "from openai import AsyncOpenAI\n",
    "\n",
    "\n",
    "from semantic_kernel.kernel import Kernel\n",
    "from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion\n",
    "from semantic_kernel.agents import ChatCompletionAgent\n",
    "from semantic_kernel.contents import ChatHistory\n",
    "\n",
    "\n",
    "from semantic_kernel.agents.open_ai import OpenAIAssistantAgent\n",
    "from semantic_kernel.contents import AuthorRole, ChatMessageContent\n",
    "from semantic_kernel.functions import kernel_function\n",
    "\n",
    "from semantic_kernel.connectors.ai import FunctionChoiceBehavior\n",
    "\n",
    "from semantic_kernel.contents.function_call_content import FunctionCallContent\n",
    "from semantic_kernel.contents.function_result_content import FunctionResultContent\n",
    "from semantic_kernel.functions import KernelArguments, kernel_function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define a sample plugin for the sample\n",
    "class DestinationsPlugin:\n",
    "    \"\"\"A List of Destinations for vacation.\"\"\"\n",
    "\n",
    "    @kernel_function(description=\"Provides a list of vacation desinations.\")\n",
    "    def get_destinations(self) -> Annotated[str, \"Returns the specials from the menu.\"]:\n",
    "        return \"\"\"\n",
    "        Barcelona, Spain\n",
    "        Paris, France\n",
    "        Berlin, Germany\n",
    "        \"\"\"\n",
    "\n",
    "    @kernel_function(description=\"Provides the availability of a destination.\")\n",
    "    def get_availability(\n",
    "        self, destination: Annotated[str, \"The destination to check availability for.\"]\n",
    "    ) -> Annotated[str, \"Returns the availability of the destination.\"]:\n",
    "        return \"\"\"\n",
    "        Barcelona - Unavailable\n",
    "        Paris - Available\n",
    "        Berlin - Available\n",
    "        \"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "client = AsyncOpenAI(\n",
    "    api_key=os.environ[\"GITHUB_TOKEN\"], base_url=\"https://models.inference.ai.azure.com/\")\n",
    "\n",
    "kernel = Kernel()\n",
    "kernel.add_plugin(DestinationsPlugin(), plugin_name=\"destinations\")\n",
    "\n",
    "service_id = \"agent\"\n",
    "\n",
    "chat_completion_service = OpenAIChatCompletion(\n",
    "    ai_model_id=\"gpt-4o-mini\",\n",
    "    async_client=client,\n",
    "    service_id=service_id\n",
    ")\n",
    "kernel.add_service(chat_completion_service)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "settings = kernel.get_prompt_execution_settings_from_service_id(\n",
    "    service_id=service_id)\n",
    "settings.function_choice_behavior = FunctionChoiceBehavior.Auto()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "AGENT_NAME = \"TravelAgent\"\n",
    "AGENT_INSTRUCTIONS = \"Answer questions about the travel destinations and their availability.\"\n",
    "# Create the agent\n",
    "agent = ChatCompletionAgent(\n",
    "    service_id=service_id,\n",
    "    kernel=kernel,\n",
    "    name=AGENT_NAME,\n",
    "    instructions=AGENT_INSTRUCTIONS,\n",
    "    arguments=KernelArguments(settings=settings),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "# User: 'What destinations are available?'\n",
      "# Assistant - TravelAgent: 'The available travel destinations are:\n",
      "- Barcelona, Spain- Paris, France- Berlin, Germany'\n",
      "# User: 'Is Barcelona available?'\n",
      "# Assistant - TravelAgent: 'Barcelona is currently unavailable. However, Paris and Berlin are available.'\n"
     ]
    }
   ],
   "source": [
    "async def main():\n",
    "    # Define the chat history\n",
    "    chat_history = ChatHistory()\n",
    "\n",
    "    # Respond to user input\n",
    "    user_inputs = [\n",
    "        \"What destinations are available?\",\n",
    "        \"Is Barcelona available?\",\n",
    "    ]\n",
    "\n",
    "    for user_input in user_inputs:\n",
    "        # Add the user input to the chat history\n",
    "        chat_history.add_user_message(user_input)\n",
    "        print(f\"# User: '{user_input}'\")\n",
    "\n",
    "        agent_name: str | None = None\n",
    "        print(\"# Assistant - \", end=\"\")\n",
    "        async for content in agent.invoke_stream(chat_history):\n",
    "            if not agent_name:\n",
    "                agent_name = content.name\n",
    "                print(f\"{agent_name}: '\", end=\"\")\n",
    "            if (\n",
    "                not any(isinstance(item, (FunctionCallContent, FunctionResultContent))\n",
    "                        for item in content.items)\n",
    "                and content.content.strip()\n",
    "            ):\n",
    "                print(f\"{content.content}\", end=\"\", flush=True)\n",
    "        print(\"'\")\n",
    "\n",
    "await main()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
